package cn.chiship.framework.upms.biz.system.service.impl;

import cn.chiship.framework.common.constants.CommonCacheConstants;
import cn.chiship.framework.common.util.FrameworkUtil2;
import cn.chiship.sdk.cache.service.RedisService;
import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.base.constants.BaseConstants;
import cn.chiship.sdk.core.util.ObjectUtil;
import cn.chiship.sdk.core.util.PrintUtil;
import cn.chiship.sdk.core.util.StringUtil;
import cn.chiship.sdk.framework.base.BaseServiceImpl;
import cn.chiship.framework.upms.biz.system.mapper.UpmsCategoryDictMapper;
import cn.chiship.framework.upms.biz.system.entity.UpmsCategoryDict;
import cn.chiship.framework.upms.biz.system.entity.UpmsCategoryDictExample;
import cn.chiship.framework.upms.biz.system.service.UpmsCategoryDictService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 分类字典业务接口实现层 2024/10/13
 *
 * @author lijian
 */
@Service
public class UpmsCategoryDictServiceImpl extends BaseServiceImpl<UpmsCategoryDict, UpmsCategoryDictExample>
        implements UpmsCategoryDictService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UpmsCategoryDictServiceImpl.class);

    @Resource
    UpmsCategoryDictMapper upmsCategoryDictMapper;

    @Autowired
    RedisService redisService;

    @Override
    public BaseResult treeTable(UpmsCategoryDictExample upmsCategoryDictExample) {
        List<UpmsCategoryDict> upmsCategoryDicts = upmsCategoryDictMapper.selectByExample(upmsCategoryDictExample);
        cacheCategoryDict();
        return BaseResult.ok(assemblyCategoryDictTree("0", upmsCategoryDicts));
    }

    @Override
    public BaseResult cacheTreeTable(String type) {
        String idKey = CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_CATEGORY_DICT_PREFIX) + ":id";

        Map<Object, Object> maps = redisService.hget(idKey);
        List<UpmsCategoryDict> upmsCategoryDicts = new ArrayList<>();
        for (Map.Entry<Object, Object> entry : maps.entrySet()) {
            UpmsCategoryDict upmsCategoryDict = (UpmsCategoryDict) entry.getValue();
            upmsCategoryDicts.add(upmsCategoryDict);
        }
        upmsCategoryDicts.sort((o1, o2) -> o2.getOrders().compareTo(o1.getOrders()));
        upmsCategoryDicts = upmsCategoryDicts.stream().filter(dict -> {
            if (!StringUtil.isNullOrEmpty(dict.getType())) {
                return dict.getType().equals(type);
            }
            return false;
        }).collect(Collectors.toList());
        return BaseResult.ok(assemblyCategoryDictTree("0", upmsCategoryDicts));
    }

    private List<JSONObject> assemblyCategoryDictTree(String pid, List<UpmsCategoryDict> upmsCategoryDicts) {
        List<JSONObject> treeVos = new ArrayList<>();
        for (UpmsCategoryDict categoryDict : upmsCategoryDicts) {
            if (pid.equals(categoryDict.getPid())) {
                treeVos.add(JSON.parseObject(JSON.toJSONString(categoryDict)));
            }
        }
        for (int i = 0; i < treeVos.size(); i++) {
            List<JSONObject> children = assemblyCategoryDictTree(treeVos.get(i).getString("id"), upmsCategoryDicts);
            if (!children.isEmpty()) {
                treeVos.get(i).put("children", children);
            }
        }
        return treeVos;
    }

    @Override
    public JSONObject assembleData(UpmsCategoryDict categoryDict) {
        JSONObject json = JSON.parseObject(JSON.toJSONString(categoryDict));
        json.putAll(getParentInfoByTreeNumber(categoryDict.getTreeNumber()));
        return json;
    }

    @Override
    public BaseResult selectDetailsByPrimaryKey(Object id) {
        UpmsCategoryDict upmsCategoryDict = super.selectByPrimaryKey(id);
        if (ObjectUtil.isEmpty(upmsCategoryDict)) {
            return BaseResult.ok();
        }
        return BaseResult.ok(assembleData(upmsCategoryDict));
    }

    @Override
    public BaseResult generateTreeNumber(String pid) {
        String treeNumber = FrameworkUtil2.generateTreeNumber(upmsCategoryDictMapper.getTreeNumberByPid(pid));
        if (StringUtil.isNullOrEmpty(treeNumber)) {
            return BaseResult.error("生成层级出错？");
        }
        return BaseResult.ok(treeNumber);
    }

    @Override
    public BaseResult insertSelective(UpmsCategoryDict upmsCategoryDict) {
        BaseResult baseResult = generateTreeNumber(upmsCategoryDict.getPid());
        if (!baseResult.isSuccess()) {
            return baseResult;
        }
        upmsCategoryDict.setTreeNumber(baseResult.getData().toString());

        return super.insertSelective(upmsCategoryDict);
    }

    @Override
    public BaseResult updateByPrimaryKeySelective(UpmsCategoryDict upmsCategoryDict) {
        return super.updateByPrimaryKeySelective(upmsCategoryDict);
    }

    @Override
    public void cacheCategoryDict() {
        String idKey = CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_CATEGORY_DICT_PREFIX) + ":id";
        String treeKey = CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_CATEGORY_DICT_PREFIX) + ":tree";

        redisService.del(treeKey);
        redisService.del(idKey);
        UpmsCategoryDictExample upmsCategoryDictExample = new UpmsCategoryDictExample();
        upmsCategoryDictExample.createCriteria().andIsDeletedEqualTo(BaseConstants.NO);
        List<UpmsCategoryDict> upmsCategoryDicts = upmsCategoryDictMapper.selectByExample(upmsCategoryDictExample);
        upmsCategoryDicts.forEach(categoryDict -> {
            redisService.hset(idKey, categoryDict.getId(), categoryDict);
            if (!StringUtil.isNullOrEmpty(categoryDict.getTreeNumber())) {
                redisService.hset(treeKey, categoryDict.getTreeNumber(), categoryDict);
            }

        });
    }

    @Override
    public String cacheGetTreeNumberById(String id) {
        String idKey = CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_CATEGORY_DICT_PREFIX) + ":id";

        UpmsCategoryDict categoryDict = (UpmsCategoryDict) redisService.hget(idKey, id);
        if (ObjectUtil.isEmpty(categoryDict)) {
            return null;
        }
        return categoryDict.getTreeNumber();
    }

    @Override
    public JSONObject getParentInfoById(String id) {
        return getParentInfoByTreeNumber(cacheGetTreeNumberById(id));
    }

    @Override
    public JSONObject getParentInfoByTreeNumber(String treeNumber) {
        JSONObject json = new JSONObject();

        String treeKey = CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_CATEGORY_DICT_PREFIX) + ":tree";

        if (StringUtil.isNullOrEmpty(treeNumber)) {
            return json;
        }
        List<String> treeNumbers = FrameworkUtil2.getAllParentTreeNumber(treeNumber);
        List<String> ids = new ArrayList<>();
        List<String> names = new ArrayList<>();
        for (String tree : treeNumbers) {
            if (!"0000".equals(tree)) {
                UpmsCategoryDict categoryDict = (UpmsCategoryDict) redisService.hget(treeKey, tree);
                if (ObjectUtil.isNotEmpty(categoryDict)) {
                    ids.add(categoryDict.getId());
                    names.add(categoryDict.getName());
                }

            }

        }
        json.put("_fullCategoryIds", ids);
        json.put("_fullCategoryNames", names);
        json.put("_fullCategoryId", StringUtil.join(ids, ","));
        json.put("_fullCategoryName", StringUtil.join(names, "/"));
        return json;
    }

    @Override
    public String getCategoryNameById(String id, Boolean isFull) {
        JSONObject json = getParentInfoById(id);
        if (Boolean.TRUE.equals(isFull)) {
            return json.getString("_fullCategoryName");
        }
        List<String> categoryNames = json.getObject("_fullCategoryNames", List.class);
        return categoryNames.get(categoryNames.size() - 1);
    }

}
